package com.zhu.esyblog.Aop;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.zhu.esyblog.pojo.RespBean;
import lombok.extern.slf4j.Slf4j;

import org.apache.commons.codec.digest.DigestUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.time.Duration;


@Aspect
@Component
@Slf4j
public class CacheAspect {
    @Autowired
    private RedisTemplate<String,String> redisTemplate;


    @Pointcut("@annotation(com.zhu.esyblog.Aop.Cache)")
    public void pt(){

    }

    @Around("pt()")
    public Object around(ProceedingJoinPoint joinPoint){
        Signature signature = joinPoint.getSignature();
        String simpleName = joinPoint.getTarget().getClass().getSimpleName();
        String name = signature.getName();
        Class[] parameterTypes=new Class[joinPoint.getArgs().length];
        Object[] args = joinPoint.getArgs();
        String params="";
        try{
            for (int i=0;i<args.length;i++){
                if(args[i]!=null){
                    params+= JSON.toJSONString(args[i]);
                    parameterTypes[i]=args[i].getClass();
                }else {
                    parameterTypes[i]=null;
                }
            }
            if(StringUtils.isNotBlank(params)){
                 params = DigestUtils.md5Hex(params);
            }
            Method method = joinPoint.getSignature().getDeclaringType().getMethod(name, parameterTypes);
            Cache annotation=method.getAnnotation(Cache.class);
            long expire = annotation.expire();
            String name1 = annotation.name();
            String redisKey=name1+"::"+simpleName+"::"+name+"::"+params;
            String value = redisTemplate.opsForValue().get(redisKey);
            if(StringUtils.isNotBlank(value)){
                log.info("存入缓存：{},{}",simpleName,name);
                return JSON.parseObject(value, RespBean.class);
            }
            Object proceed = joinPoint.proceed();
            redisTemplate.opsForValue().set(redisKey,JSON.toJSONString(proceed), Duration.ofMillis(expire));
            log.info("走了缓存:{},{}",simpleName,name);
            return proceed;
        }catch (Exception e){
            e.printStackTrace();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
          return RespBean.error("系统错误！",999);
    }
}
